<?php
include_once BXD_INCLUDEPATH . 'core/Action.php';
include_once BXD_INCLUDEPATH . 'core/Controller.php';
include_once BXD_INCLUDEPATH . 'core/Redirect.php';

$response	= NULL;

/**
 * Core di BXDFramework
 * Qui avviene l'inizializzazione di tutte le funzioni principali necessarie al
 * corretto funzionamento del sistema
 *
 * @author Fabrizio Filieri
 */
class BXD
{
	private		$controller			= null;
	private		$action				= null;
	private		$view				= null;
	private		$layout				= null;
	private		$query				= null;
	private		$controllerClass	= null;

	public function run()
	{
		global $response, $bxd, $session, $post, $aliasController;

		/**
		 * Le seguenti istruzioni inizializzano CONTROLLER e ACTION esplodendo la URL tramite il
		 * separatore '/'. Se l'URL risulta essere vuota vengono impostati i valori di default
		 */

		$requestUrl = $_GET['bmvc_query'];

		if($requestUrl != "")
		{
			if(USE_ALIAS_URL)
			{
				include_once BXD_INCLUDEPATH_SITE . '/include/conf/aliasURL.php';

				$tempUrl = explode("/", $requestUrl);

				$aliasSearch = NULL;

				foreach($alias_url as $alias)
				{
					if(strpos($alias['alias_' . $_SESSION['lang']], $tempUrl[0]))
					{
						$aliasSearch = $alias;
						
						break;
					}
				}

				if($aliasSearch !== NULL)
				{
					$control = substr($aliasSearch['real_url'], 0, 1);
					$requestUrl = (($control == '/') ? substr($aliasSearch['real_url'], 1) : $aliasSearch['real_url']);

					for($i = $aliasSearch['start_count_from_explode_url']; $i < count($tempUrl); $i++)
						$requestUrl .= $tempUrl[$i] . (($i != count($tempUrl) - 1) ? '/' : '');
				}
			}

			$this->query = explode("/", $requestUrl);

			$controllerName = $this->query[0];
			$actionName		= $this->query[1];

			$this->controller 	= $controllerName;
			$this->action 		= $actionName;
		}
		else
		{
			$this->controller 	= BXD_CONTROLLER_DEFAULT;
			$this->action 		= BXD_ACTION_DEFAULT;
		}

		/**
		 * Verifica se nel file 'config.php' è stato settato che deve essere effettuato
		 * il controllo dei permessi di accesso. In tal caso viene chiamata la funzione
		 * initSystemAccessControl() che verifica tutte le impostazioni restituendo il
		 * risultato del controllo come valore BOOLEANO
		 */

		if(BXD_CLASS_ACCESS_CONTROL !== NULL && BXD_CLASS_ACCESS_CONTROL != "")
		{
			if(!$this->initSystemAccessControl()) return;
		}

		if (file_exists(BXD_INCLUDEPATH_SITE . 'controller/' . $this->controller . ".php"))
		{
			include_once BXD_INCLUDEPATH_SITE . 'controller/' . $this->controller . '.php';

			$this->controllerClass = new $this->controller();

			$params = array();

			for($i = 2; $i < count($this->query); $i++)
				$params[] = $this->query[$i];

			$this->controllerClass->setView($this->controller . "/" . $this->action);

			//--> Verifico se esiste metodo specificato nell'url. Se si lo richiamo passando eventuali valori

			if (method_exists($this->controllerClass, $this->action))
			{
				try
				{
					call_user_func_array(array($this->controllerClass, $this->action), $params);

					$this->layout	= $this->controllerClass->getLayout();
					$this->view		= $this->controllerClass->getView();

					$response = $this->controllerClass->getResponse();
				}
				catch(DatabaseConnectionErrorException $e)
				{
					$response = new Response();
					$response->message = $e->getMessage();

					$this->layout 	= BXD_LAYOUT_ERROR;
					$this->view 	= PAGE_CONNECT_DB_ERROR;
				}
			}

			if (file_exists(BXD_INCLUDEPATH_SITE . 'view/' . $this->view . '.page.php'))
			{
				if (!isset($this->layout))
					$this->layout = BXD_LAYOUT_DEFAULT;
					
				include_once BXD_INCLUDEPATH_SITE . 'layout/' . $this->layout . '.php';
			}
			else
			{
				$this->view = BXD_PAGE_NOTFOUND;
				include_once BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ERROR . '.php';
			}
		}
		else
		{
			$this->view = BXD_PAGE_NOTFOUND;
			include_once BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ERROR . '.php';
		}
	}

	/**
	 * Metodo utilizzato per sollevare nuove eccezioni customizzate
	 *
	 * @param String $exception	Nome dell'eccezione che si intende sollevare
	 * @param String $message	Valore da attribuire all'eccezione
	 */

	public static function newException($exception, $message)
	{
		include_once BXD_INCLUDEPATH . 'lib/exception/' . $exception . 'Exception.php';
		$exceptionClass = $exception . "Exception";
		
		throw new $exceptionClass($message);
	}

	/**
	 * Restituisce il contenuto per il layout.
	 *
	 * @return string $response il contenuto dell'azione per il layout
	 */

	public function getContentForLayout()
	{
		global $response, $bxd, $session, $post;

		include(BXD_INCLUDEPATH_SITE . 'view/' . $this->view . '.page.php');
	}

	/**
	 * Metodo che stampa il contenuto delgli head specificati nel view con estensione '.head'
	 */

	public function printHead()
	{
		if (file_exists(BXD_INCLUDEPATH_SITE . 'view/' . $this->view . '.head.php'))
		{
			include_once BXD_INCLUDEPATH_SITE . 'view/' . $this->view . '.head.php';
		}
	}

	/*** ------------ *** METODI INTERNI NON ACCESSIBILI DALL'ESTERNO *** ------------ ***/

	/**
	 * Questo metodo si occupa di verificare i permessi di accesso a determinati Controller e
	 * Action. Viene richiamato quando nel file di configurazione viene settato il parametro
	 * USE_ACCESS_CONTROL = TRUE. Il seguente metodo analizza la tramite il metodo 'check'
	 * della classe specificata nel config.php se il controller e la action presenti nell'URL
	 * hanno i permessi per essere visualizzati altrimenti si viene reindirizzati verso il
	 * layout BXD_LAYOUT_ACCESS_CONTROL o BXD_LAYOUT_ERROR.
	 *
	 * @global Response $response	Oggetto utilizzato per il passaggio dei parametri tra Contreller e View
	 * @global BXD $bxd				Core del Framework
	 * @global Session $session		Oggetto per la gestione della Sessione
	 * @return Boolean				Risultato del controllo
	 */

	private function initSystemAccessControl()
	{
		include_once BXD_INCLUDEPATH . 'core/AccessControl.php';

		$acc = BXD_CLASS_ACCESS_CONTROL;

		if(file_exists(BXD_INCLUDEPATH_SITE . 'class/' . BXD_CLASS_ACCESS_CONTROL . '.php'))
		{
			include_once BXD_INCLUDEPATH_SITE . 'class/' . BXD_CLASS_ACCESS_CONTROL . '.php';

			$accessControl = new $acc();
			$accessControlResult = $accessControl->check($this->controller, $this->action);

			if(is_bool($accessControlResult))
			{
				if(!$accessControlResult)
				{
					global $response, $bxd, $session, $post;

					$this->view = BXD_PAGE_ACCESS_DENIED;

					if(file_exists(BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ACCESS_CONTROL . '.php'))
					{
						include_once BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ACCESS_CONTROL . '.php';
					}
					else // Se non esiste carico il layout di default
					{
						include_once BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ERROR . '.php';
					}

					return FALSE;
				}
			}
			else
			{
				if(file_exists(BXD_INCLUDEPATH_SITE . 'layout/' . $accessControlResult . '.php'))
				{
					include_once BXD_INCLUDEPATH_SITE . 'layout/' . $accessControlResult . '.php';
				}
				else // Se non esiste carico il layout di default
				{
					include_once BXD_INCLUDEPATH_SITE . 'layout/' . BXD_LAYOUT_ERROR . '.php';
				}

				return FALSE;
			}
		}

		return TRUE;
	}
}

?>
